﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Reflection;

namespace PickGold.Util.WordSpliter
{
	/// <summary>
	/// 匹配中文人名
	/// </summary>
	class ChineseName
	{
		internal Dictionary<char, List<char>> Surnames;
		internal Dictionary<char, char> MonoNames;
		internal Dictionary<char, char> MiddleNames;
		internal Dictionary<char, char> SuffixNames;

		public ChineseName(string[] surname, char[] mono, char[] middle, char[] suffix)
		{
			this.Surnames = new Dictionary<char, List<char>>();
			this.MonoNames = new Dictionary<char, char>();
			this.MiddleNames = new Dictionary<char, char>();
			this.SuffixNames = new Dictionary<char, char>();
			if (mono != null)
			{
				foreach (var c in mono)
					this.MonoNames[c] = c;
			}
			if (middle != null)
			{
				foreach (var c in middle)
					this.MiddleNames[c] = c;
			}
			if (suffix != null)
			{
				foreach (var c in suffix)
					this.SuffixNames[c] = c;
			}
			this.Surname(surname);
		}

		private void Surname(string[] surnames)
		{
			if (surnames == null)
				return;

			var dic = new Dictionary<char, List<char>>();
			foreach (var name in surnames)
			{
				if (string.IsNullOrWhiteSpace(name))
					continue;

				if (name.Length == 1)
				{
					if (!dic.ContainsKey(name[0]))
						dic.Add(name[0], null);
					continue;
				}

				var ls = new List<char>();
				if (dic.ContainsKey(name[0]))
				{
					if (dic[name[0]] == null)
					{
						ls.Add((char)0);
						dic[name[0]] = ls;
					}

					dic[name[0]].Add(name[1]);
				}
				else
				{
					ls.Add(name[1]);
					dic[name[0]] = ls;
				}
			}
			Surnames = dic;
		}

		public List<string> Match(string text, int start)
		{
			var result = Reflector<string>.NullList;
			var cur = start;

			if (cur > text.Length - 2)
				return result;

			var f1 = text[cur];
			cur++;
			var f2 = text[cur];

			var f2List = Reflector<char>.NullList;
			if (!this.Surnames.TryGetValue(f1, out f2List))
				return null;

			if (f2List != null)
			{
				var find = false;
				var hasZero = false;
				foreach (var c in f2List)
				{
					if (c == f2)
					{
						//复姓
						cur++;
						find = true;
						break;
					}
					
					if (c == 0)//单姓，首字和某个复姓的首字相同
						hasZero = true;
				}

				if (!find && !hasZero)
					return null;
			}

			if (cur >= text.Length)
				return null;

			var name1 = text[cur];

			if (this.MonoNames.ContainsKey(name1))
			{
				result = new List<string>();
				result.Add(text.Substring(start, cur - start + 1));
			}

			if (this.MiddleNames.ContainsKey(name1))
			{
				cur++;

				if (cur >= text.Length)
					return result;

				var name2 = text[cur];
				if (this.SuffixNames.ContainsKey(name2))
				{
					if (result == null)
						result = new List<string>();
					result.Add(text.Substring(start, cur - start + 1));
				}
			}

			return result;
		}
	}
}
